package com.mux.zip;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;


/***
 * apache common-compress 压缩下的工具
 * 
 * @author devin.chen
 *
 */
public class CommZipUtil {
	

		/**
	     * ZIP文件后缀名
	     */
		public static final String ZIP_FILE_SUFFIX = ".zip";
	
	    /*
		 * 对文件列表进行压缩
	     * <p/>
	     * 注意：<br/>
	     *  1、文件如果为目录，会循环递归压缩目录里面的文件,但不会压缩目录<br/>
	     *  2、如果文件不存在，则直接忽略；
	     *  
	     *  
		 * @param zip  zip包文件目录,以 .zip 结尾
		 * @param files   文件列表
		 */
	    public static final void zip(String zipFile, List<String> files) {
	    	if(files!=null && files.size()!=0){
	    		
	    		try(ZipArchiveOutputStream   zaos = new ZipArchiveOutputStream(new File(zipFile))){
	    		    // Use Zip64 extensions for all entries where they are required
	    			zaos.setUseZip64(Zip64Mode.AsNeeded);
	    			for(String file : files){
	    				compress(zaos, new File(file));
	    			}
	    			zaos.finish();
	    			zaos.close();
	    		}catch(Exception e){
	    			 throw new RuntimeException("[压缩文件]-压缩文件异常, ZIP[" + zipFile + "], Files[" + files + "]！", e);
	    		}
	    	}
	    
	    }
	    
	    
	    /**
	     * 
	     * 
	     * @param out
	     * @param file
	     */
	    public static void compress(ZipArchiveOutputStream out,File file){
	    	//目录
	    	if(file.isDirectory()){
	    		compressDirectory(out, file);
	    	}else{
	    		compressFile(out, file);
	    	}
	    			
	    	
	    }
	    
	    
	    
	    /**
	     * 压缩单个文件
	     * 
	     * @param out
	     * @param file
	     */
	    public static final void compressFile(ZipArchiveOutputStream out, File file) {
	    	
	    	InputStream is = null;
	    	try {
		    	    ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(file, file.getName());
	                out.putArchiveEntry(zipArchiveEntry);
	                is = new FileInputStream(file);
	                byte[] buffer = new byte[1024 * 5];
	                int len = -1;
	                while ((len = is.read(buffer)) != -1) {
	                   // 把缓冲区的字节写入到ZipArchiveEntry
	                    out.write(buffer, 0, len);
	               	}
	               out.closeArchiveEntry();
           } catch (Exception e) {
           	 	new RuntimeException("[压缩文件]-压缩文件异常, ZIP[" + out + "], Files[" + file + "]！", e);
           } finally {
               if (is != null)
					try {
						is.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
           }
	    }
	    
	    
	    
	    /**
	     * 压缩目录
	     * 
	     * 
	     * @param out
	     * @param dir
	     */
	    public static final void compressDirectory(ZipArchiveOutputStream out, File dir) {
	    	
	    	try{
	    		// 目录不存在
	            if (!dir.exists()) {
	                return;
	            }
	            // 压缩目录下所有的文件
	            File[] files = dir.listFiles();
	            for (int i = 0; i < files.length; i++) {
	            	// 遍历压缩所有非ZIP文件
	                if (files[i].getName().indexOf(ZIP_FILE_SUFFIX) < 0) {
	                    compress(out, files[i]);
	                }
	            }
	    		
	    	}catch(Exception e){
	    		throw new RuntimeException("[压缩文件]-压缩目录异常, ZIP[" + out + "], DIR[" + dir + "]！", e);
	    	}
	    }
	    
	    
	    
	    
	    public static void main(String[] args) {
	    	List<String> list = new ArrayList<String>();
	    	list.add("E:\\test-compress");
	    	
	    	zip("e:\\test-compress.zip", list);
	    	
		}
	    
	    
}
